1 Verwendete Packages und Vorgehen

Für die verwendung dieses Notebooks benötigen Sie die folgenden installatierten Packages:

Als Datensatz wird 2021-2022 Football Team Stats verwendet, den bei Kaggle https://www.kaggle.com/datasets/vivovinco/20212022-football-team-stats gefunden wurde. Es geht dabei um eine Statistik von Fußball Meisterschaften aus den 5 Besten Europa Ligas(Frankreich, Deutschland,Spanien,Italien und England).Darin gibt es insgesamt 20 Merkmale bzw Atribute wie(Attendance, Goalscored, Bestscorer, Pts, GD, usw.), die im folgenden erläutert werden. Rk: vom Datentyp Numeric entspricht die Platzierung der Mannschaft im Datensatz.Sie werden in der absteigenden Reihenfolge sortiert. D.h die Mannschaft mit der höchsten erreichten Punkte zu den niedrigsten. Squad: vom Datentyp Character ist der Name der Mannschaft,Country:vom Datentyp Character ist Name des Landes, LgRk: vom Datentyp Numeric ist die Position der Mannschaft in seiner Meisterschaft, MP: vom Datentyp Numeric ist die Anzahl von gespielten Spiele, W: vom Datentyp Numeric ist die Anzahl der gewonnenen Spiele, D: vom Datentyp Numeric ist die Anzahl Unentschiedene Spiele, L:vom Datentyp Numeric ist die Anzahl der verlorenen Spiele, GF:vom Datentyp Numeric ist die Anzahl der erzielten Tore, GA: vom Datentyp Numeric ist die Anzah der kassierten Tore, GD: vom Datentyp Numeric entspricht die Tordifferenz, Pts: Punktstand, Pts/G: Punkte pro Spiel, xG:erwartete Tore, xGA:erwartete kassierte Tore, xGD:erwartete Tordifferenz, xGD/90:erwartete Tordifferenz nach 90 Minuten, Last 5: letzte funf Ergebnisse, Attendance:Durchschnitt der Besucherzahl im Stadion, BestScorer GoalScored:vom Datentyp Character entspricht den Name des Bestschiessers und Anzahl der erzielten Tore, Goalkeeper: Torwart

Diese Merkmale sind aber nicht vollständig bzw illustrieren nicht ganz genau die Mannschaften. Es gibt andere Merkmale wie die Anzahl der Roten und Gelben Karten, die Anzahl von Fehlern, erfolgreiche Pässe, Zweikämpfe usw., die die Meisterschaften besser illustrieren können. Die verfügbare Merkmale sind nur ein Teil einer größeren Obermenge.

Der Datensatz wird ganz einfach mithilfe von read_delim eingelesen, da die Merkmale durch ein Semikolon getrennt werden. Danach werden sie in einem Data frame ausgelagert. Der Grund dafür ist einfach. Mit einem Data frame und mithilfe von dem Pipeline, Filter, select, mutate,usw. ist es möglich nur auf bestimmte Merkmale zuzugreifen und das vereinfacht die Visualisierung.

2 Untersuchung

Bei der Betrachtung eines Datensatzes bzw eines Fußball Datensatzes kann man sich unterschiedlichen Fragen stellen und zwar: 1) Was sind die Absoluten Häufigkeiten der verfügbaren Länder(Wieviel mal kommen die Länder vor)? 2) Wie sieht die Besucherzahl im Stadien aus? D.h in welcher Liga werden die Spiele mehr oder weniger besucht? 3)Was ist Das Punktverhältnis zwischen die Länder? D.h wieviele Punkte wurden in Jedem Land durch die Mannschaften erreicht? 4) Welche Mannschaften verlieren bzw gewinnen weniger oder mehr als den Schnitt? 5)Welche Mannschaften Scoren viel oder weniger als den Schnitt und in welchen Länder gibt es die besten Scorer. usw.. ==> und Vieles mehr.. Diese Fragen werden wir einfach mitfhilfe von ggplot und ggplotly visualisieren und danach interpretieren, was wir erfunden haben.

3 Häufigkeiten der Länder

In unserem Datensatz gibt es insgesamt 98 Mannschaften. Wir wollen erstmal sehen, wie sich die Mannschaften in den Länder verteilen. D.h wie viel Mannschaften jedes Land beinhaltet. Dafür benutzen wir einen Barplot und wir greifen auf die Spalte Country, die die Namen der Länder enthält, zu. Am Ende wird nun einen Barplot mit unterschiedlichen Farben und eine Legende hinzugefügt.


count<-table(X2021_2022_Football_Team_Stats$Country)
p2<-barplot(count,main="5  Besten Europa Meisterschaften und Ihre Häufigkeiten",xlab="Name der Länder",ylab="Absolute Häufigkeiten",legend=rownames(count),col=c("green","red","blue","orange","yellow"))

NA
NA

Aus der Visualisierung ist es zu bemerken, dass die Häufigkeiten der Länder pro Mannschaft fast gleich aussieht. Jedes Land enthält in unserem Datensatz 20 Mannschaften, nur die Deutsche Liga besteht aus 18 Mannschaften.

4 Menschenmassen in Stadien

Hierbei wollen wir herausfinden, wie viele Mannschaften pro Land wenig besucht werden. Dafür nehmen wir die Spalte Attendance. Diese Spalte enthält die durchschnittliche Besucherzahl der Mannschaften nach 37 SpielTage. Dann machen wir eine mutate mit der Spalte average. Dies entspricht den Durschnitt von den 98 Mannschaften. Zum schluss machen wir eine Filterung von Ländern, die unterhalb der Spalte average liegen und wir machen eine Selektion von den Name des Landes(Country),Name der Mannschaft(Squad) und Attendance. Dieser Histogramm wird Rot gefarbt,um anzudeuten, dass die Mannschaften etwas schlechtes (kleine Besucherzahl) aufweisen


hallo2<- Erg %>%
  mutate(
    average=sum(Attendance)/98,
    
  ) %>%
  filter(Attendance<average) %>%
     select(Squad, Country,Attendance)

p<-ggplot(hallo2 , mapping=aes(x=Country)) +
  geom_histogram(fill="red", color="red",stat="count" , breaks=seq(0, 20,4)) +
  
  labs(
    title="5 Besten Meisterschaften", 
    subtitle="Anzahl von Mannschaften pro Land mit wenigen Attendance",
    x="Name von Länder", 
    y="Absolute Häufigkeiten"
  ) +
  coord_flip()
Warning: Ignoring unknown parameters: binwidth, bins, pad, breaks
  ggplotly(p)

Aus dieser Visualisierung folgt, dass alle Länder auherhalb Großbritanien eine Schlechte Besucherzahl bei den Spielen aufweisen. Die schechteste Davon ist Italien Mit 80% der Mannschaften mit einer Besucherzahl unter dem Schnitt. Nur die Englische Liga wird über 85 % der Spiele über den Schnitt besucht.

5 Punktverhältnis der Länder und Pie Chart Verteilung

Hier wollen wir sehen wieviele Punkte wurden in jeder Ligameisterschaft nach 37 Spieltage gesammelt. Dafür machen wir eine Gruppierung nach der Spalte Country. Dann die Summe von Pts(Pts ist dabei die erreichendete Punkte Pro Mannschaft nach 37 Spieltage). Diese Summe wird dann Pro Land jeweils in einer neuen Mutate Spalte(summe) hinzugefügt. Zum Schluss machen wir eine Selektion der Spalten Country(Name der Länder), Squad(Mannschaft Name),summe(die neue Spalte).


hallo3 <-  Erg %>%
  group_by(Country) %>%
  mutate(
    summe=sum(Pts),
    
  ) %>%
  select(Squad, Country,summe)

p2<-ggplot(hallo3,aes(Country, summe)) + 
  geom_point(size = 3) + 
  geom_line()+
  labs(
    title="5 Besten Länder und die Summe ihrer gesamten Punkten", 
    x="Name von Länder", 
    y="Gesamte Summe der Punkten"
  ) 
ggplotly(p2)
NA

Im zweiten Pie Chart Verteilung nehmen wir einfach die vorherigen berechneten Summe Pro Länder und Wir repräsentieren jedes Land mit seiner Prozentualen Leistung nach der Saison. Als Farbe benutzen wir die unterschiedlichen Farben des Regenbogens, um die Länder miteinander zu unterscheiden.

slices<- c(1009,1009,1001,845,1010)
lbls<-c("England","Italien","Spanien","Deutschland","Frankreich")
pct<-round(slices/sum(slices)*100)
lbls<-paste(lbls, " ",pct, "%", seq="" )
pie(slices ,labels=lbls, main="Pie Chart Verteilung der Länder nach der Saison", col=rainbow(5))

Bemerkenswert ist das 4 Länder(Frankreich, Großbritannien,Spanien und Italien) nach 37 Spieltage die gleiche aufgerundete Leistung erbracht haben nämlich 21%. Nur Deutschland hat nur 17% erbracht. Ein möglicher Grund dafür besteht darin, dass es in der Deutschen Liga nur 18 Mannschaften gibt, wenn die anderen über 20 Mannschaften verfügen. D.h es wird kaum vorkommen, dass die erreichte Punkte in Deutschland am Ende der Saison gleich wie in anderen Länder aussieht, da die Mannschaftenanzahl kleiner ist.

6 Mannschaften mit gutem Tordifferenz

In dieser Visualisierung wollen wir bestimmen, welche Mannschaften eine gute Tordifferenz besitzt. Dafür benötigen wir die Spalte GD(Goal Difference =Tore erzielt minus Tore Kassiert). Diese Spalte enthält dann die Tordifferenz von jeder Mannschaft nach 37 Spieltage. Wir machen dann eine Mutate mit der Spalte average. Dies entspricht den Schnitt der Tordifferenzen aller Mannschaten. Danach machen wir eine Filterung der Mannschaften die oberhalb der Average liegen und zum Schluss eine Selektion der Spalten(Squad, GD und average)

hallo7<-Erg %>%
  mutate(
    average=sum(GD)/98
  ) %>%
  filter(GD> average) %>%
 select(Squad,GD,average)

p6<-ggplot(hallo7) +
  geom_point(mapping=aes(x=GD, y=Squad), 
             color="brown",fill="brown") +
  labs(
    title=" gute Mannschaften mit Tordifferenz ober den Schnitt ", 
    y="Name von Mannschaften", 
    x="Tordifferenz der Mannschaften"
  ) 
ggplotly(p6)
NA
NA
NA

Aus dieser Visualisierung lässt sich herausfinden,dass ungefähr 46% der verfügbaren Mannschaften eine Tordifferenz über den Durchschnitt besitzen. Dabei ist immer die englische Meisterschaft an der Spitze mit mehr als ein drittel der Mannschaften und an letzten Stelle steht die Italienische Meisterschaft mit nur 7 Mannschaften.

7 Mannschaften die mehr als den Schnitt gewonnen haben

Hierbei wollen wir die Mannschaften, die über den Schnitt gewinnen.Dabei greifen wir auf die Spalte W zu. Diese Spalte enthält alle gewonnenen Spiele der Mannschaften nach 37 Spiele. Wir machen wie üblich eine neue Spalte, die die Average der gewonnenen Spiele berechnet und am Ende eine Filter der Merkmale die oberhalb liegen und eine Selektion der Spalten(Squad, W und die neue Spalte Average).

hallo5<-Erg %>%
  mutate(
    average=sum(W)/98
  ) %>%
  filter(W> average) %>%
 select(Squad,W,average)
p3<-ggplot(hallo5) +
  geom_point(mapping=aes(x=W, y=Squad), 
             color="blue",fill="blue") +
  labs(
    title=" Beste Mannschaften die ueber der Average gewinnen", 
    y="Name von Mannschaften", 
    x="Anzahl von gewonnenen Spielen"
  )
ggplotly(p3)
NA

Bei der Gewinnquote zeigt immer noch die Englische Meisterschaft, warum sie als beste Fussball Liga gilt. Manchester city aus England steht immer noch an der Spitze mit mehr als den Doppel des Durchschnitts. Hierbei ist die französische Liga an der letzten Stelle mit wenigen Mannschaften Dabei.

8 Spieler mit der Besten GPMA(Tor pro Spiel Durchschnitt)

GPMA=Anzahl von erzielten Toren/ Anzahl von Spielen . Zum ersten wird einen neuen Datensatz hallogt erstellt, wobei die Spalte Top Team Scorer in Zwei Spalten(BestScorer und GoalScored) geteilt wird. Eine Spalte mit dem Name des Schießers und eine andere Mit seinen erzielten Toren. Danach erzeugen wir die Spalte GPMA und die Spalte Average . GPMA entspricht den Torschnitt von jedem Spieler nach der Anzahl der gespielten Spiele. Average ist einfach der Schnit der GPMA aller Mannschaften.

hallogt<-Erg %>% separate(col = "Top Team Scorer", into = c("BestScorer","GoalScored"), sep=" - ")

hallo11<- hallogt %>%
  mutate(
    GPMA=as.numeric(GoalScored)/MP,
    Average=sum(GPMA)/98
    
  ) %>% 
  filter(GPMA> Average) %>%
  select(BestScorer, GoalScored ,GPMA,Country)
p9<-ggplot(hallo11) +
  geom_point(mapping=aes(x=GPMA , y=BestScorer ), 
             color="maroon",fill="maroon") +
  labs(
    title="  Schiesser die über den GPMA scoren", 
    y="Name der Spieler", 
    x="Tor pro Spiel Durchschnitt der Spieler"
  )
ggplotly(p9)
NA

9 Schiessverhältnis zwischen die Ligas mit BestSchießer über den Schnitt

Zum ersten wird einen neuen Dataframe hallogt erstellt, wobei die Spalte Top Team Scorer in Zwei Spalten(BestScorer und GoalScored) geteilt wird. Eine Spalte mit dem Name des Schießers und eine andere Mit seinen erzielten Toren. Danach machen wir eine Gruppierung über die Spalte Country und eine neue Spalte Average wird hinzugefügt. Dies enthält den Schnitt der erzielten Toren und am Ende machen wir eine Selektion der erzielten Tore oberhalb der Average

hallogt<-Erg %>% separate(col = "Top Team Scorer", into = c("BestScorer","GoalScored"), sep=" - ")

hallo10<-hallogt %>%
  group_by(Country)%>%
  mutate(
    Average=sum(as.numeric(GoalScored))/98
    
  ) %>% 
  filter(GoalScored > Average) %>%
  select(BestScorer, GoalScored ,Average,Country)

p8<-ggplot(hallo10 , mapping=aes(x=Country)) +
     geom_bar(fill="orange", color="black") +
     labs(
         title=" Ligas Goalausgleich", 
         subtitle=" Ligas mit mehr und Weniger BestSchießer",
         x="Name von Länder", 
         y="Anzahl der BestSchießer pro Land"
     ) 
ggplotly(p8)
NA

Die Deutsche Liga hat wenige Mannschaften als die andere Länder aber besitzt ein Drittel der besseren ToreSchießer der lertzten Saison. Zu beachten ist, dass Italien mit nur 6 Beteiligten steht immer an der letzten Stelle. Die Italienische Liga wird nicht nur unter den Schnitt besichtigt, sondern die Mannschaften und Spieler schießen nicht so viele. Diese Gründe weisen einfach nach, warum die Italienische Liga als schwere Liga gekennzeichnet wird.

10 überraschende Ergebnisse

ein größes überraschendes Ergebnis besteht darin, dass insgesamt 4 Meisterschaften(Großbritannien, Frankreich, Italien und Spanien) die gleiche aufgerundete Leistung(jeweils 21% der punkten) am Ende der Saison gesammelt haben. Sie verfügen über unterschiedliche Tordiffernz, Erwartete Toren , Bestschießer und bei manchen Meisterschaften gibt es sogar mehr als 50 % der Meisterschaften, die wenig Tore erzielen. Wir können darunter verstehen, dass die Torquote einer Mannschaft keinen Stärkeren Einfluss auf den Gewinn oder Verlust eines Spiels hat.

Eine weitere Überraschung liegt daran, dass die Deutsche Meisterschaft wenige Spieler bzw Stürmer hat, weil sie nur 18 Mannschaften hat, wenn die anderen Ligas über 20 Verfügen. Sie aber die Liga mit den besten Stürmer die mehr als den Schnitt schießen.

11 Kristischer Ausblick

Es ist immer schwer seine eigene Arbeit zu beurteilen, aber nur die eigene Beiteiligten wissen, welcher Aufwand und welche Schwierigkeiten sie bei der Erledigung der Arbeit erlebt haben. In dieser Arbeit war die Idee mit einem Flexdashboard(in den beiden ersten versionen) die Daten zu visualisieren ungeeignet. Der Grund dafür ist einfach. Damit kann man nicht gleichzeitig visualisieren und Text hinzufügen, bzw den Code ansehen. Aber nach zwei Versionen ist ein Notebook für diese Visualisierung zum Einsatz gekommen und hat uns die Sachen erleichtert und die Visualisierungen ist unserer Meinung nach nachvollziehbarer geworden. Besser hätten wir direkt mit einem Notebook angefangen und wir wären früh fertig geworden. Aber dies hat uns ermöglicht sowohl mit Flexdashboard als auch Notebook zu arbeiten. Das kann für uns nur ein Vorteil sein.

Verwendete Quellen https://www.delftstack.com/de/howto/r/separate-in-r/: Wurde benutzt, weil wir eine Spalte in zwei Spalten aufteilen wollten.

Character Encoding in the RStudio IDE – RStudio Support: Mit UTF-8 haben wir Probleme zum Einlesen Manche Charakter gekriegt Daher haben wir uns diese Encoding Quelle Seite angeschaut, um unsere passende Encoding auszuwählen.

Geleisteten Arbeitszeit

Zur Erledigung dieser Arbeit haben wir ungefähr 47 Stunden.(innerhalb 4 Wochen) für die erste Version gebraucht. Für die zweite Version 10 Stunden innerhalb einer Woche.Für die dritte Version haben wir 23 Stunden gebraucht, um es fertigzustellen. Das ergibt eine gesamte Arbeitsaufwand von 80 Stunden.

LS0tDQp0aXRsZTogIkZ1w59iYWxsIEFuYWx5c2UgZGVyIGxldHp0ZW4gU2Fpc29uIGF1cyBkZW4gNSBCZXN0ZW4gRXVyb3BhIExpZ2FtZWlzdGVyc2NoYWZ0ZW4gIg0KYXV0aG9yOiAiSGFuYW4gV2FuZGppIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazoNCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0aGVtZTogY29zbW8NCiAgICB0b2M6IHllcw0KICAgIGVuY29kaW5nOiB1dGYtOCAgIA0KICBodG1sX2RvY3VtZW50OiANCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgdGhlbWU6IGNvc21vDQogICAgaGlnaGxpZ2h0OiBweWdtZW50cw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KZW5jb2Rpbmc6IHV0Zi04DQotLS0NCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0KbGlicmFyeShkcGx5cikNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KGRwbHlyKSkNCmxpYnJhcnkocGxvdHJpeCkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShSQ29sb3JCcmV3ZXIpDQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShSQ29sb3JCcmV3ZXIpKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeSh0aWR5dmVyc2UpKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy53aWR0aCA9IDUsIGZpZy5hc3AgPSAxLzMpDQpYMjAyMV8yMDIyX0Zvb3RiYWxsX1RlYW1fU3RhdHMgPC0gcmVhZF9kZWxpbSgiQzovVXNlcnMvSEFOQU4gV0FOREpJL0Rlc2t0b3AvVkRBL2RhdGEvMjAyMS0yMDIyIEZvb3RiYWxsIFRlYW0gU3RhdHMuY3N2IiwgDQogICAgZGVsaW0gPSAiOyIsIGVzY2FwZV9kb3VibGUgPSBGQUxTRSwgbG9jYWxlID0gbG9jYWxlKGVuY29kaW5nID0gIklTTy04ODU5LTIiKSwgDQogICAgdHJpbV93cyA9IFRSVUUpDQoNCiAgICANCkVyZzwtIGFzLmRhdGEuZnJhbWUoWDIwMjFfMjAyMl9Gb290YmFsbF9UZWFtX1N0YXRzKQ0KDQpgYGANCg0KDQojIFZlcndlbmRldGUgUGFja2FnZXMgdW5kIFZvcmdlaGVuDQpGw7xyIGRpZSB2ZXJ3ZW5kdW5nIGRpZXNlcyBOb3RlYm9va3MgYmVuw7Z0aWdlbiBTaWUgZGllIGZvbGdlbmRlbiBpbnN0YWxsYXRpZXJ0ZW4gUGFja2FnZXM6DQoNCi0gdGlkeXZlcnNlDQotIHBsb3RseQ0KLSBSQ29sb3JCcmV3ZXINCi0gZ2dwbG90Mg0KLSBkcGx5cg0KLSBwbG90cml4DQoNCg0KQWxzIERhdGVuc2F0eiB3aXJkICoyMDIxLTIwMjIgRm9vdGJhbGwgVGVhbSBTdGF0cyogdmVyd2VuZGV0LCBkZW4gYmVpICpLYWdnbGUqIGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvdml2b3ZpbmNvLzIwMjEyMDIyLWZvb3RiYWxsLXRlYW0tc3RhdHMgIGdlZnVuZGVuIHd1cmRlLiBFcyBnZWh0IGRhYmVpIHVtIGVpbmUgU3RhdGlzdGlrIHZvbiBGdcOfYmFsbCBNZWlzdGVyc2NoYWZ0ZW4gYXVzIGRlbiA1IEJlc3RlbiBFdXJvcGEgTGlnYXMoRnJhbmtyZWljaCwgRGV1dHNjaGxhbmQsU3BhbmllbixJdGFsaWVuIHVuZCBFbmdsYW5kKS5EYXJpbiBnaWJ0IGVzIGluc2dlc2FtdCAyMCBNZXJrbWFsZSBiencgQXRyaWJ1dGUgd2llKEF0dGVuZGFuY2UsIEdvYWxzY29yZWQsIEJlc3RzY29yZXIsIFB0cywgR0QsIHVzdy4pLCBkaWUgaW0gZm9sZ2VuZGVuIGVybMOkdXRlcnQgd2VyZGVuLg0KKlJrKjogdm9tIERhdGVudHlwIE51bWVyaWMgZW50c3ByaWNodCBkaWUgUGxhdHppZXJ1bmcgZGVyIE1hbm5zY2hhZnQgaW0gRGF0ZW5zYXR6LlNpZSB3ZXJkZW4gaW4gZGVyIGFic3RlaWdlbmRlbiBSZWloZW5mb2xnZSBzb3J0aWVydC4gRC5oIGRpZSBNYW5uc2NoYWZ0IG1pdCBkZXIgaMO2Y2hzdGVuIGVycmVpY2h0ZW4gUHVua3RlIHp1IGRlbiBuaWVkcmlnc3Rlbi4NCipTcXVhZCo6IHZvbSBEYXRlbnR5cCBDaGFyYWN0ZXIgaXN0IGRlciBOYW1lIGRlciBNYW5uc2NoYWZ0LCpDb3VudHJ5Kjp2b20gRGF0ZW50eXAgQ2hhcmFjdGVyIGlzdCAgTmFtZSBkZXMgTGFuZGVzLCAqTGdSayo6IHZvbSBEYXRlbnR5cCBOdW1lcmljIGlzdCBkaWUgUG9zaXRpb24gZGVyIE1hbm5zY2hhZnQgaW4gc2VpbmVyIE1laXN0ZXJzY2hhZnQsICpNUCo6IHZvbSBEYXRlbnR5cCBOdW1lcmljIGlzdCBkaWUgQW56YWhsIHZvbiBnZXNwaWVsdGVuIFNwaWVsZSwgKlcqOiB2b20gRGF0ZW50eXAgTnVtZXJpYyBpc3QgZGllIEFuemFobCBkZXIgZ2V3b25uZW5lbiBTcGllbGUsICpEKjogdm9tIERhdGVudHlwIE51bWVyaWMgaXN0IGRpZSBBbnphaGwgVW5lbnRzY2hpZWRlbmUgU3BpZWxlLCAqTCo6dm9tIERhdGVudHlwIE51bWVyaWMgaXN0IGRpZSBBbnphaGwgZGVyIHZlcmxvcmVuZW4gU3BpZWxlLCAqR0YqOnZvbSBEYXRlbnR5cCBOdW1lcmljIGlzdCBkaWUgQW56YWhsIGRlciBlcnppZWx0ZW4gVG9yZSwgKkdBKjogdm9tIERhdGVudHlwIE51bWVyaWMgaXN0IGRpZSBBbnphaCBkZXIga2Fzc2llcnRlbiBUb3JlLCAqR0QqOiB2b20gRGF0ZW50eXAgTnVtZXJpYyBlbnRzcHJpY2h0IGRpZSBUb3JkaWZmZXJlbnosICpQdHMqOiBQdW5rdHN0YW5kLCAqUHRzL0cqOiBQdW5rdGUgcHJvIFNwaWVsLCAqeEcqOmVyd2FydGV0ZSBUb3JlLCAqeEdBKjplcndhcnRldGUga2Fzc2llcnRlIFRvcmUsICp4R0QqOmVyd2FydGV0ZSBUb3JkaWZmZXJlbnosICp4R0QvOTAqOmVyd2FydGV0ZSBUb3JkaWZmZXJlbnogbmFjaCA5MCBNaW51dGVuLCAqTGFzdCA1KjogbGV0enRlIGZ1bmYgRXJnZWJuaXNzZSwgKkF0dGVuZGFuY2UqOkR1cmNoc2Nobml0dCBkZXIgQmVzdWNoZXJ6YWhsIGltIFN0YWRpb24sICpCZXN0U2NvcmVyIEdvYWxTY29yZWQqOnZvbSBEYXRlbnR5cCBDaGFyYWN0ZXIgZW50c3ByaWNodCBkZW4gTmFtZSBkZXMgQmVzdHNjaGllc3NlcnMgdW5kIEFuemFobCBkZXIgZXJ6aWVsdGVuIFRvcmUsICpHb2Fsa2VlcGVyKjogVG9yd2FydA0KDQpEaWVzZSBNZXJrbWFsZSBzaW5kIGFiZXIgbmljaHQgdm9sbHN0w6RuZGlnIGJ6dyBpbGx1c3RyaWVyZW4gbmljaHQgZ2FueiBnZW5hdSBkaWUgTWFubnNjaGFmdGVuLiBFcyBnaWJ0IGFuZGVyZSBNZXJrbWFsZSB3aWUgZGllIEFuemFobCBkZXIgUm90ZW4gdW5kIEdlbGJlbiBLYXJ0ZW4sIGRpZSBBbnphaGwgdm9uIEZlaGxlcm4sIGVyZm9sZ3JlaWNoZSBQw6Rzc2UsIFp3ZWlrw6RtcGZlIHVzdy4sIGRpZSBkaWUgTWVpc3RlcnNjaGFmdGVuIGJlc3NlciBpbGx1c3RyaWVyZW4ga8O2bm5lbi4gRGllIHZlcmbDvGdiYXJlIE1lcmttYWxlIHNpbmQgbnVyIGVpbiBUZWlsIGVpbmVyIGdyw7bDn2VyZW4gT2Jlcm1lbmdlLg0KDQpEZXIgRGF0ZW5zYXR6IHdpcmQgZ2FueiBlaW5mYWNoIG1pdGhpbGZlIHZvbiByZWFkX2RlbGltIGVpbmdlbGVzZW4sIGRhIGRpZSBNZXJrbWFsZSBkdXJjaCBlaW4gU2VtaWtvbG9uIGdldHJlbm50IHdlcmRlbi4gRGFuYWNoIHdlcmRlbiBzaWUgaW4gZWluZW0gRGF0YSBmcmFtZSBhdXNnZWxhZ2VydC4gRGVyIEdydW5kIGRhZsO8ciBpc3QgZWluZmFjaC4gTWl0IGVpbmVtIERhdGEgZnJhbWUgdW5kIG1pdGhpbGZlIHZvbiBkZW0gUGlwZWxpbmUsIEZpbHRlciwgc2VsZWN0LCBtdXRhdGUsdXN3LiBpc3QgZXMgbcO2Z2xpY2ggbnVyIGF1ZiBiZXN0aW1tdGUgTWVya21hbGUgenV6dWdyZWlmZW4gdW5kIGRhcyB2ZXJlaW5mYWNodCBkaWUgVmlzdWFsaXNpZXJ1bmcuDQoNCiMgVW50ZXJzdWNodW5nDQoNCkJlaSBkZXIgQmV0cmFjaHR1bmcgZWluZXMgRGF0ZW5zYXR6ZXMgYnp3IGVpbmVzIEZ1w59iYWxsIERhdGVuc2F0emVzIGthbm4gbWFuIHNpY2ggdW50ZXJzY2hpZWRsaWNoZW4gRnJhZ2VuIHN0ZWxsZW4gdW5kIHp3YXI6DQogMSkgV2FzIHNpbmQgZGllIEFic29sdXRlbiBIw6R1Zmlna2VpdGVuIGRlciB2ZXJmw7xnYmFyZW4gTMOkbmRlcihXaWV2aWVsIG1hbCANCmtvbW1lbiBkaWUgTMOkbmRlciB2b3IpPw0KMikgV2llIHNpZWh0IGRpZSBCZXN1Y2hlcnphaGwgaW0gU3RhZGllbiBhdXM/IEQuaCBpbiB3ZWxjaGVyIExpZ2Egd2VyZGVuIGRpZSBTcGllbGUgbWVociBvZGVyIHdlbmlnZXIgYmVzdWNodD8NCjMpV2FzIGlzdCBEYXMgUHVua3R2ZXJow6RsdG5pcyB6d2lzY2hlbiBkaWUgTMOkbmRlcj8gRC5oIHdpZXZpZWxlIFB1bmt0ZSB3dXJkZW4gaW4gSmVkZW0gTGFuZCBkdXJjaCBkaWUgTWFubnNjaGFmdGVuIGVycmVpY2h0Pw0KNCkgV2VsY2hlIE1hbm5zY2hhZnRlbiB2ZXJsaWVyZW4gYnp3IGdld2lubmVuIHdlbmlnZXIgb2RlciBtZWhyIGFscyBkZW4gU2Nobml0dD8NCjUpV2VsY2hlIE1hbm5zY2hhZnRlbiBTY29yZW4gdmllbCBvZGVyIHdlbmlnZXIgYWxzIGRlbiBTY2huaXR0IHVuZCBpbiB3ZWxjaGVuIEzDpG5kZXIgZ2lidCBlcyBkaWUgYmVzdGVuIFNjb3Jlci4gdXN3Li4NCj09PiB1bmQgVmllbGVzIG1laHIuLg0KRGllc2UgRnJhZ2VuIHdlcmRlbiB3aXIgZWluZmFjaCBtaXRmaGlsZmUgdm9uIGdncGxvdCB1bmQgZ2dwbG90bHkgdmlzdWFsaXNpZXJlbiB1bmQgZGFuYWNoIGludGVycHJldGllcmVuLCB3YXMgd2lyIGVyZnVuZGVuIGhhYmVuLg0KDQoNCg0KIyBIw6R1Zmlna2VpdGVuIGRlciBMw6RuZGVyDQoNCkluIHVuc2VyZW0gRGF0ZW5zYXR6IGdpYnQgZXMgaW5zZ2VzYW10IDk4IE1hbm5zY2hhZnRlbi4gV2lyIHdvbGxlbiBlcnN0bWFsIHNlaGVuLCB3aWUgc2ljaCBkaWUgTWFubnNjaGFmdGVuIGluIGRlbiBMw6RuZGVyIHZlcnRlaWxlbi4gRC5oIHdpZSB2aWVsIE1hbm5zY2hhZnRlbiBqZWRlcyBMYW5kIGJlaW5oYWx0ZXQuIERhZsO8ciBiZW51dHplbiB3aXIgZWluZW4gQmFycGxvdCB1bmQgd2lyIGdyZWlmZW4gYXVmIGRpZSBTcGFsdGUgQ291bnRyeSwgZGllIGRpZSBOYW1lbiBkZXIgTMOkbmRlciBlbnRow6RsdCwgenUuIEFtIEVuZGUgd2lyZCBudW4gZWluZW4gQmFycGxvdCBtaXQgdW50ZXJzY2hpZWRsaWNoZW4gRmFyYmVuIHVuZCBlaW5lIExlZ2VuZGUgaGluenVnZWbDvGd0Lg0KDQoNCg0KDQpgYGB7cn0NCg0KY291bnQ8LXRhYmxlKFgyMDIxXzIwMjJfRm9vdGJhbGxfVGVhbV9TdGF0cyRDb3VudHJ5KQ0KcDI8LWJhcnBsb3QoY291bnQsbWFpbj0iNSAgQmVzdGVuIEV1cm9wYSBNZWlzdGVyc2NoYWZ0ZW4gdW5kIElocmUgSMOkdWZpZ2tlaXRlbiIseGxhYj0iTmFtZSBkZXIgTMOkbmRlciIseWxhYj0iQWJzb2x1dGUgSMOkdWZpZ2tlaXRlbiIsbGVnZW5kPXJvd25hbWVzKGNvdW50KSxjb2w9YygiZ3JlZW4iLCJyZWQiLCJibHVlIiwib3JhbmdlIiwieWVsbG93IikpDQoNCg0KYGBgDQoNCkF1cyBkZXIgVmlzdWFsaXNpZXJ1bmcgaXN0IGVzIHp1IGJlbWVya2VuLCBkYXNzIGRpZSBIw6R1Zmlna2VpdGVuIGRlciBMw6RuZGVyIHBybyBNYW5uc2NoYWZ0IGZhc3QgZ2xlaWNoIGF1c3NpZWh0LiBKZWRlcyBMYW5kIGVudGjDpGx0IGluIHVuc2VyZW0gRGF0ZW5zYXR6IDIwIE1hbm5zY2hhZnRlbiwgbnVyIGRpZSBEZXV0c2NoZSBMaWdhIGJlc3RlaHQgYXVzIDE4IE1hbm5zY2hhZnRlbi4NCg0KIyBNZW5zY2hlbm1hc3NlbiBpbiBTdGFkaWVuDQoNCkhpZXJiZWkgd29sbGVuIHdpciBoZXJhdXNmaW5kZW4sIHdpZSB2aWVsZSBNYW5uc2NoYWZ0ZW4gcHJvIExhbmQgd2VuaWcgYmVzdWNodCB3ZXJkZW4uIERhZsO8ciBuZWhtZW4gd2lyIGRpZSBTcGFsdGUgKkF0dGVuZGFuY2UqLiBEaWVzZSBTcGFsdGUgZW50aMOkbHQgZGllIGR1cmNoc2Nobml0dGxpY2hlIEJlc3VjaGVyemFobCBkZXIgTWFubnNjaGFmdGVuIG5hY2ggMzcgU3BpZWxUYWdlLg0KRGFubiBtYWNoZW4gd2lyIGVpbmUgbXV0YXRlIG1pdCBkZXIgU3BhbHRlICphdmVyYWdlKi4gRGllcyBlbnRzcHJpY2h0IGRlbiBEdXJzY2huaXR0IHZvbiBkZW4gOTggTWFubnNjaGFmdGVuLiBadW0gc2NobHVzcyBtYWNoZW4gd2lyIGVpbmUgRmlsdGVydW5nIHZvbiBMw6RuZGVybiwgZGllIHVudGVyaGFsYiBkZXIgU3BhbHRlICphdmVyYWdlKiBsaWVnZW4gdW5kIHdpciBtYWNoZW4gZWluZSBTZWxla3Rpb24gdm9uIGRlbiBOYW1lIGRlcyBMYW5kZXMoQ291bnRyeSksTmFtZSBkZXIgTWFubnNjaGFmdChTcXVhZCkgdW5kICpBdHRlbmRhbmNlKi4NCkRpZXNlciBIaXN0b2dyYW1tIHdpcmQgUm90IGdlZmFyYnQsdW0gYW56dWRldXRlbiwgZGFzcyBkaWUgTWFubnNjaGFmdGVuICBldHdhcyBzY2hsZWNodGVzIChrbGVpbmUgQmVzdWNoZXJ6YWhsKSBhdWZ3ZWlzZW4NCg0KDQoNCg0KDQpgYGB7cn0NCg0KaGFsbG8yPC0gRXJnICU+JQ0KICBtdXRhdGUoDQogICAgYXZlcmFnZT1zdW0oQXR0ZW5kYW5jZSkvOTgsDQogICAgDQogICkgJT4lDQogIGZpbHRlcihBdHRlbmRhbmNlPGF2ZXJhZ2UpICU+JQ0KICAgICBzZWxlY3QoU3F1YWQsIENvdW50cnksQXR0ZW5kYW5jZSkNCg0KcDwtZ2dwbG90KGhhbGxvMiAsIG1hcHBpbmc9YWVzKHg9Q291bnRyeSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oZmlsbD0icmVkIiwgY29sb3I9InJlZCIsc3RhdD0iY291bnQiICwgYnJlYWtzPXNlcSgwLCAyMCw0KSkgKw0KICANCiAgbGFicygNCiAgICB0aXRsZT0iNSBCZXN0ZW4gTWVpc3RlcnNjaGFmdGVuIiwgDQogICAgc3VidGl0bGU9IkFuemFobCB2b24gTWFubnNjaGFmdGVuIHBybyBMYW5kIG1pdCB3ZW5pZ2VuIEF0dGVuZGFuY2UiLA0KICAgIHg9Ik5hbWUgdm9uIEzDpG5kZXIiLCANCiAgICB5PSJBYnNvbHV0ZSBIw6R1Zmlna2VpdGVuIg0KICApICsNCiAgY29vcmRfZmxpcCgpDQogIGdncGxvdGx5KHApDQpgYGANCkF1cyBkaWVzZXIgVmlzdWFsaXNpZXJ1bmcgZm9sZ3QsIGRhc3MgYWxsZSBMw6RuZGVyIGF1aGVyaGFsYiBHcm/Dn2JyaXRhbmllbiANCmVpbmUgU2NobGVjaHRlIEJlc3VjaGVyemFobCBiZWkgZGVuIFNwaWVsZW4gYXVmd2Vpc2VuLiBEaWUgc2NoZWNodGVzdGUgRGF2b24gaXN0IEl0YWxpZW4gTWl0IDgwJSBkZXIgTWFubnNjaGFmdGVuIG1pdCBlaW5lciBCZXN1Y2hlcnphaGwgdW50ZXIgZGVtIFNjaG5pdHQuIE51ciBkaWUgRW5nbGlzY2hlIExpZ2Egd2lyZCDDvGJlciA4NSAlIGRlciBTcGllbGUgw7xiZXIgZGVuIFNjaG5pdHQgYmVzdWNodC4NCg0KIyBQdW5rdHZlcmjDpGx0bmlzIGRlciBMw6RuZGVyIHVuZCBQaWUgQ2hhcnQgVmVydGVpbHVuZw0KDQpIaWVyIHdvbGxlbiB3aXIgc2VoZW4gd2lldmllbGUgUHVua3RlIHd1cmRlbiBpbiBqZWRlciBMaWdhbWVpc3RlcnNjaGFmdCBuYWNoDQozNyBTcGllbHRhZ2UgZ2VzYW1tZWx0LiBEYWbDvHIgbWFjaGVuIHdpciBlaW5lIEdydXBwaWVydW5nIG5hY2ggZGVyIFNwYWx0ZSAqQ291bnRyeSouIERhbm4gZGllIFN1bW1lIHZvbiAqUHRzKihQdHMgaXN0IGRhYmVpIGRpZSBlcnJlaWNoZW5kZXRlIFB1bmt0ZSBQcm8gTWFubnNjaGFmdCBuYWNoIDM3IFNwaWVsdGFnZSkuIERpZXNlIFN1bW1lIHdpcmQgZGFubiBQcm8gTGFuZCBqZXdlaWxzIGluIGVpbmVyIG5ldWVuICpNdXRhdGUqIFNwYWx0ZShzdW1tZSkgaGluenVnZWbDvGd0LiBadW0gU2NobHVzcyBtYWNoZW4gd2lyIGVpbmUNClNlbGVrdGlvbiBkZXIgU3BhbHRlbiBDb3VudHJ5KE5hbWUgZGVyIEzDpG5kZXIpLCBTcXVhZChNYW5uc2NoYWZ0IE5hbWUpLHN1bW1lKGRpZSBuZXVlIFNwYWx0ZSkuDQoNCg0KDQoNCg0KYGBge3J9DQoNCmhhbGxvMyA8LSAgRXJnICU+JQ0KICBncm91cF9ieShDb3VudHJ5KSAlPiUNCiAgbXV0YXRlKA0KICAgIHN1bW1lPXN1bShQdHMpLA0KICAgIA0KICApICU+JQ0KICBzZWxlY3QoU3F1YWQsIENvdW50cnksc3VtbWUpDQoNCnAyPC1nZ3Bsb3QoaGFsbG8zLGFlcyhDb3VudHJ5LCBzdW1tZSkpICsgDQogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgDQogIGdlb21fbGluZSgpKw0KICBsYWJzKA0KICAgIHRpdGxlPSI1IEJlc3RlbiBMw6RuZGVyIHVuZCBkaWUgU3VtbWUgaWhyZXIgZ2VzYW10ZW4gUHVua3RlbiIsIA0KICAgIHg9Ik5hbWUgdm9uIEzDpG5kZXIiLCANCiAgICB5PSJHZXNhbXRlIFN1bW1lIGRlciBQdW5rdGVuIg0KICApIA0KZ2dwbG90bHkocDIpDQoNCmBgYA0KSW0gendlaXRlbiBQaWUgQ2hhcnQgVmVydGVpbHVuZyBuZWhtZW4gd2lyIGVpbmZhY2ggZGllIHZvcmhlcmlnZW4gYmVyZWNobmV0ZW4gU3VtbWUgUHJvIEzDpG5kZXIgdW5kIFdpciByZXByw6RzZW50aWVyZW4gamVkZXMgTGFuZCBtaXQgc2VpbmVyIFByb3plbnR1YWxlbiBMZWlzdHVuZyBuYWNoIGRlciBTYWlzb24uIEFscyBGYXJiZSBiZW51dHplbiB3aXIgZGllIHVudGVyc2NoaWVkbGljaGVuIEZhcmJlbiBkZXMgUmVnZW5ib2dlbnMsIHVtIGRpZSBMw6RuZGVyIG1pdGVpbmFuZGVyIHp1IHVudGVyc2NoZWlkZW4uDQoNCmBgYHtyfQ0Kc2xpY2VzPC0gYygxMDA5LDEwMDksMTAwMSw4NDUsMTAxMCkNCmxibHM8LWMoIkVuZ2xhbmQiLCJJdGFsaWVuIiwiU3BhbmllbiIsIkRldXRzY2hsYW5kIiwiRnJhbmtyZWljaCIpDQpwY3Q8LXJvdW5kKHNsaWNlcy9zdW0oc2xpY2VzKSoxMDApDQpsYmxzPC1wYXN0ZShsYmxzLCAiICIscGN0LCAiJSIsIHNlcT0iIiApDQpwaWUoc2xpY2VzICxsYWJlbHM9bGJscywgbWFpbj0iUGllIENoYXJ0IFZlcnRlaWx1bmcgZGVyIEzDpG5kZXIgbmFjaCBkZXIgU2Fpc29uIiwgY29sPXJhaW5ib3coNSkpDQoNCmBgYA0KQmVtZXJrZW5zd2VydCBpc3QgZGFzIDQgTMOkbmRlcihGcmFua3JlaWNoLCBHcm/Dn2JyaXRhbm5pZW4sU3BhbmllbiB1bmQgSXRhbGllbikgbmFjaCAzNyBTcGllbHRhZ2UgIGRpZSBnbGVpY2hlIGF1ZmdlcnVuZGV0ZSBMZWlzdHVuZyBlcmJyYWNodCBoYWJlbiBuw6RtbGljaCAyMSUuIE51ciBEZXV0c2NobGFuZCBoYXQgbnVyIDE3JSBlcmJyYWNodC4gRWluIG3DtmdsaWNoZXIgR3J1bmQgZGFmw7xyIGJlc3RlaHQgZGFyaW4sIGRhc3MgZXMgaW4gZGVyICBEZXV0c2NoZW4gTGlnYSBudXIgMTggTWFubnNjaGFmdGVuIGdpYnQsIHdlbm4gZGllIGFuZGVyZW4gw7xiZXIgMjAgTWFubnNjaGFmdGVuIHZlcmbDvGdlbi4gRC5oIGVzIHdpcmQga2F1bSB2b3Jrb21tZW4sIGRhc3MgZGllIGVycmVpY2h0ZSBQdW5rdGUgaW4gRGV1dHNjaGxhbmQgYW0gRW5kZSBkZXIgU2Fpc29uIGdsZWljaCB3aWUgaW4gYW5kZXJlbiBMw6RuZGVyIGF1c3NpZWh0LCBkYSBkaWUgTWFubnNjaGFmdGVuYW56YWhsIGtsZWluZXIgaXN0LiAgDQoNCg0KIyBNYW5uc2NoYWZ0ZW4gbWl0IGd1dGVtIFRvcmRpZmZlcmVueg0KDQpJbiBkaWVzZXIgVmlzdWFsaXNpZXJ1bmcgd29sbGVuIHdpciBiZXN0aW1tZW4sIHdlbGNoZSBNYW5uc2NoYWZ0ZW4gZWluZSBndXRlIFRvcmRpZmZlcmVueiBiZXNpdHp0LiBEYWbDvHIgYmVuw7Z0aWdlbiB3aXIgZGllIFNwYWx0ZSAqR0QqKEdvYWwgRGlmZmVyZW5jZSA9VG9yZSBlcnppZWx0IG1pbnVzIFRvcmUgS2Fzc2llcnQpLiBEaWVzZSBTcGFsdGUgZW50aMOkbHQgZGFubiBkaWUgVG9yZGlmZmVyZW56IHZvbiBqZWRlciBNYW5uc2NoYWZ0IG5hY2ggMzcgU3BpZWx0YWdlLiBXaXIgbWFjaGVuIGRhbm4gZWluZSBNdXRhdGUgbWl0IGRlciBTcGFsdGUgKmF2ZXJhZ2UqLiBEaWVzIGVudHNwcmljaHQgZGVuIFNjaG5pdHQgZGVyIFRvcmRpZmZlcmVuemVuIGFsbGVyIE1hbm5zY2hhdGVuLiBEYW5hY2ggbWFjaGVuIHdpciBlaW5lIEZpbHRlcnVuZyBkZXIgTWFubnNjaGFmdGVuIGRpZSBvYmVyaGFsYiBkZXIgQXZlcmFnZSBsaWVnZW4gdW5kIHp1bSBTY2hsdXNzIGVpbmUgU2VsZWt0aW9uIGRlciBTcGFsdGVuKFNxdWFkLCBHRCB1bmQgYXZlcmFnZSkgDQpgYGB7cn0NCmhhbGxvNzwtRXJnICU+JQ0KICBtdXRhdGUoDQogICAgYXZlcmFnZT1zdW0oR0QpLzk4DQogICkgJT4lDQogIGZpbHRlcihHRD4gYXZlcmFnZSkgJT4lDQogc2VsZWN0KFNxdWFkLEdELGF2ZXJhZ2UpDQoNCnA2PC1nZ3Bsb3QoaGFsbG83KSArDQogIGdlb21fcG9pbnQobWFwcGluZz1hZXMoeD1HRCwgeT1TcXVhZCksIA0KICAgICAgICAgICAgIGNvbG9yPSJicm93biIsZmlsbD0iYnJvd24iKSArDQogIGxhYnMoDQogICAgdGl0bGU9IiBndXRlIE1hbm5zY2hhZnRlbiBtaXQgVG9yZGlmZmVyZW56IG9iZXIgZGVuIFNjaG5pdHQgIiwgDQogICAgeT0iTmFtZSB2b24gTWFubnNjaGFmdGVuIiwgDQogICAgeD0iVG9yZGlmZmVyZW56IGRlciBNYW5uc2NoYWZ0ZW4iDQogICkgDQpnZ3Bsb3RseShwNikNCg0KDQoNCmBgYA0KQXVzIGRpZXNlciBWaXN1YWxpc2llcnVuZyBsw6Rzc3Qgc2ljaCBoZXJhdXNmaW5kZW4sZGFzcyB1bmdlZsOkaHIgNDYlIGRlciB2ZXJmw7xnYmFyZW4gTWFubnNjaGFmdGVuIGVpbmUgVG9yZGlmZmVyZW56IMO8YmVyIGRlbiBEdXJjaHNjaG5pdHQgYmVzaXR6ZW4uIERhYmVpIGlzdCBpbW1lciBkaWUgZW5nbGlzY2hlIE1laXN0ZXJzY2hhZnQgYW4gZGVyIFNwaXR6ZSBtaXQgbWVociBhbHMgZWluIGRyaXR0ZWwgIGRlciBNYW5uc2NoYWZ0ZW4gdW5kIGFuIGxldHp0ZW4gU3RlbGxlIHN0ZWh0IGRpZSBJdGFsaWVuaXNjaGUgTWVpc3RlcnNjaGFmdCBtaXQgbnVyIDcgTWFubnNjaGFmdGVuLg0KDQojIE1hbm5zY2hhZnRlbiBkaWUgbWVociBhbHMgZGVuIFNjaG5pdHQgZ2V3b25uZW4gaGFiZW4NCg0KSGllcmJlaSB3b2xsZW4gd2lyIGRpZSBNYW5uc2NoYWZ0ZW4sIGRpZSDDvGJlciBkZW4gU2Nobml0dCBnZXdpbm5lbi5EYWJlaSBncmVpZmVuIHdpciBhdWYgZGllIFNwYWx0ZSAqVyogenUuIERpZXNlIFNwYWx0ZSBlbnRow6RsdCBhbGxlIGdld29ubmVuZW4gU3BpZWxlIGRlciBNYW5uc2NoYWZ0ZW4gbmFjaCAzNyBTcGllbGUuIFdpciBtYWNoZW4gd2llIMO8YmxpY2ggZWluZSBuZXVlIFNwYWx0ZSwgZGllIGRpZSBBdmVyYWdlIGRlciBnZXdvbm5lbmVuIFNwaWVsZSBiZXJlY2huZXQgdW5kIGFtIEVuZGUgZWluZSBGaWx0ZXIgZGVyIE1lcmttYWxlIGRpZSBvYmVyaGFsYiBsaWVnZW4gdW5kIGVpbmUgU2VsZWt0aW9uIGRlciBTcGFsdGVuKFNxdWFkLCBXIHVuZCBkaWUgbmV1ZSBTcGFsdGUgQXZlcmFnZSkuDQoNCg0KYGBge3J9DQpoYWxsbzU8LUVyZyAlPiUNCiAgbXV0YXRlKA0KICAgIGF2ZXJhZ2U9c3VtKFcpLzk4DQogICkgJT4lDQogIGZpbHRlcihXPiBhdmVyYWdlKSAlPiUNCiBzZWxlY3QoU3F1YWQsVyxhdmVyYWdlKQ0KcDM8LWdncGxvdChoYWxsbzUpICsNCiAgZ2VvbV9wb2ludChtYXBwaW5nPWFlcyh4PVcsIHk9U3F1YWQpLCANCiAgICAgICAgICAgICBjb2xvcj0iYmx1ZSIsZmlsbD0iYmx1ZSIpICsNCiAgbGFicygNCiAgICB0aXRsZT0iIEJlc3RlIE1hbm5zY2hhZnRlbiBkaWUgdWViZXIgZGVyIEF2ZXJhZ2UgZ2V3aW5uZW4iLCANCiAgICB5PSJOYW1lIHZvbiBNYW5uc2NoYWZ0ZW4iLCANCiAgICB4PSJBbnphaGwgdm9uIGdld29ubmVuZW4gU3BpZWxlbiINCiAgKQ0KZ2dwbG90bHkocDMpDQoNCmBgYA0KQmVpIGRlciBHZXdpbm5xdW90ZSB6ZWlndCBpbW1lciBub2NoIGRpZSBFbmdsaXNjaGUgTWVpc3RlcnNjaGFmdCwgd2FydW0gc2llIGFscyAqYmVzdGUgRnVzc2JhbGwgTGlnYSogZ2lsdC4gIE1hbmNoZXN0ZXIgY2l0eSBhdXMgRW5nbGFuZCBzdGVodCBpbW1lciBub2NoIGFuIGRlciBTcGl0emUgbWl0IG1laHIgYWxzIGRlbiBEb3BwZWwgZGVzIER1cmNoc2Nobml0dHMuIEhpZXJiZWkgaXN0IGRpZSBmcmFuesO2c2lzY2hlIExpZ2EgYW4gZGVyIGxldHp0ZW4gU3RlbGxlIG1pdCB3ZW5pZ2VuIE1hbm5zY2hhZnRlbiBEYWJlaS4NCg0KIyBTcGllbGVyIG1pdCBkZXIgQmVzdGVuIEdQTUEoVG9yIHBybyBTcGllbCBEdXJjaHNjaG5pdHQpDQoNCkdQTUE9QW56YWhsIHZvbiBlcnppZWx0ZW4gVG9yZW4vIEFuemFobCB2b24gU3BpZWxlbg0KLg0KWnVtIGVyc3RlbiB3aXJkIGVpbmVuIG5ldWVuIERhdGVuc2F0eiAqaGFsbG9ndCogZXJzdGVsbHQsIHdvYmVpIGRpZSBTcGFsdGUgKlRvcCBUZWFtIFNjb3JlciogaW4gWndlaSBTcGFsdGVuKCpCZXN0U2NvcmVyKiB1bmQgKkdvYWxTY29yZWQqKSBnZXRlaWx0IHdpcmQuIEVpbmUgU3BhbHRlIG1pdCBkZW0gTmFtZSBkZXMgU2NoaWXDn2VycyB1bmQgZWluZSBhbmRlcmUgTWl0IHNlaW5lbiBlcnppZWx0ZW4gVG9yZW4uDQpEYW5hY2ggZXJ6ZXVnZW4gd2lyIGRpZSBTcGFsdGUgKkdQTUEqIHVuZCBkaWUgU3BhbHRlICpBdmVyYWdlKiAuIEdQTUEgZW50c3ByaWNodCBkZW4gVG9yc2Nobml0dCB2b24gamVkZW0gU3BpZWxlciBuYWNoIGRlciBBbnphaGwgZGVyIGdlc3BpZWx0ZW4gU3BpZWxlLiBBdmVyYWdlIGlzdCBlaW5mYWNoIGRlciBTY2huaXQgZGVyICpHUE1BKiBhbGxlciBNYW5uc2NoYWZ0ZW4uDQoNCmBgYHtyfQ0KaGFsbG9ndDwtRXJnICU+JSBzZXBhcmF0ZShjb2wgPSAiVG9wIFRlYW0gU2NvcmVyIiwgaW50byA9IGMoIkJlc3RTY29yZXIiLCJHb2FsU2NvcmVkIiksIHNlcD0iIC0gIikNCg0KaGFsbG8xMTwtIGhhbGxvZ3QgJT4lDQogIG11dGF0ZSgNCiAgICBHUE1BPWFzLm51bWVyaWMoR29hbFNjb3JlZCkvTVAsDQogICAgQXZlcmFnZT1zdW0oR1BNQSkvOTgNCiAgICANCiAgKSAlPiUgDQogIGZpbHRlcihHUE1BPiBBdmVyYWdlKSAlPiUNCiAgc2VsZWN0KEJlc3RTY29yZXIsIEdvYWxTY29yZWQgLEdQTUEsQ291bnRyeSkNCnA5PC1nZ3Bsb3QoaGFsbG8xMSkgKw0KICBnZW9tX3BvaW50KG1hcHBpbmc9YWVzKHg9R1BNQSAsIHk9QmVzdFNjb3JlciApLCANCiAgICAgICAgICAgICBjb2xvcj0ibWFyb29uIixmaWxsPSJtYXJvb24iKSArDQogIGxhYnMoDQogICAgdGl0bGU9IiAgU2NoaWVzc2VyIGRpZSDDvGJlciBkZW4gR1BNQSBzY29yZW4iLCANCiAgICB5PSJOYW1lIGRlciBTcGllbGVyIiwgDQogICAgeD0iVG9yIHBybyBTcGllbCBEdXJjaHNjaG5pdHQgZGVyIFNwaWVsZXIiDQogICkNCmdncGxvdGx5KHA5KQ0KDQpgYGANCg0KDQojIFNjaGllc3N2ZXJow6RsdG5pcyB6d2lzY2hlbiBkaWUgTGlnYXMgbWl0IEJlc3RTY2hpZcOfZXIgw7xiZXIgZGVuIFNjaG5pdHQNCg0KWnVtIGVyc3RlbiB3aXJkIGVpbmVuIG5ldWVuIERhdGFmcmFtZSAqaGFsbG9ndCogZXJzdGVsbHQsIHdvYmVpIGRpZSBTcGFsdGUgKlRvcCBUZWFtIFNjb3JlciogaW4gWndlaSBTcGFsdGVuKCpCZXN0U2NvcmVyKiB1bmQgKkdvYWxTY29yZWQqKSBnZXRlaWx0IHdpcmQuIEVpbmUgU3BhbHRlIG1pdCBkZW0gTmFtZSBkZXMgU2NoaWXDn2VycyB1bmQgZWluZSBhbmRlcmUgTWl0IHNlaW5lbiBlcnppZWx0ZW4gVG9yZW4uDQpEYW5hY2ggbWFjaGVuIHdpciBlaW5lIEdydXBwaWVydW5nIMO8YmVyIGRpZSBTcGFsdGUgKkNvdW50cnkqIA0KdW5kIGVpbmUgIG5ldWUgU3BhbHRlICpBdmVyYWdlKiB3aXJkIGhpbnp1Z2Vmw7xndC4gRGllcyBlbnRow6RsdCBkZW4gU2Nobml0dCBkZXIgZXJ6aWVsdGVuIFRvcmVuIHVuZCBhbSBFbmRlIG1hY2hlbiB3aXIgZWluZSBTZWxla3Rpb24gZGVyIGVyemllbHRlbiBUb3JlIG9iZXJoYWxiIGRlciBBdmVyYWdlIA0KDQpgYGB7cn0NCmhhbGxvZ3Q8LUVyZyAlPiUgc2VwYXJhdGUoY29sID0gIlRvcCBUZWFtIFNjb3JlciIsIGludG8gPSBjKCJCZXN0U2NvcmVyIiwiR29hbFNjb3JlZCIpLCBzZXA9IiAtICIpDQoNCmhhbGxvMTA8LWhhbGxvZ3QgJT4lDQogIGdyb3VwX2J5KENvdW50cnkpJT4lDQogIG11dGF0ZSgNCiAgICBBdmVyYWdlPXN1bShhcy5udW1lcmljKEdvYWxTY29yZWQpKS85OA0KICAgIA0KICApICU+JSANCiAgZmlsdGVyKEdvYWxTY29yZWQgPiBBdmVyYWdlKSAlPiUNCiAgc2VsZWN0KEJlc3RTY29yZXIsIEdvYWxTY29yZWQgLEF2ZXJhZ2UsQ291bnRyeSkNCg0KcDg8LWdncGxvdChoYWxsbzEwICwgbWFwcGluZz1hZXMoeD1Db3VudHJ5KSkgKw0KICAgICBnZW9tX2JhcihmaWxsPSJvcmFuZ2UiLCBjb2xvcj0iYmxhY2siKSArDQogICAgIGxhYnMoDQogICAgICAgICB0aXRsZT0iIExpZ2FzIEdvYWxhdXNnbGVpY2giLCANCiAgICAgICAgIHN1YnRpdGxlPSIgTGlnYXMgbWl0IG1laHIgdW5kIFdlbmlnZXIgQmVzdFNjaGllw59lciIsDQogICAgICAgICB4PSJOYW1lIHZvbiBMw6RuZGVyIiwgDQogICAgICAgICB5PSJBbnphaGwgZGVyIEJlc3RTY2hpZcOfZXIgcHJvIExhbmQiDQogICAgICkgDQpnZ3Bsb3RseShwOCkNCg0KYGBgDQoNCkRpZSBEZXV0c2NoZSBMaWdhIGhhdCB3ZW5pZ2UgTWFubnNjaGFmdGVuIGFscyBkaWUgYW5kZXJlIEzDpG5kZXIgYWJlciBiZXNpdHp0IGVpbiBEcml0dGVsIGRlciBiZXNzZXJlbiBUb3JlU2NoaWXDn2VyIGRlciBsZXJ0enRlbiBTYWlzb24uIFp1IGJlYWNodGVuIGlzdCwgZGFzcyBJdGFsaWVuIG1pdCBudXIgNiBCZXRlaWxpZ3RlbiBzdGVodCBpbW1lciBhbiBkZXIgbGV0enRlbiBTdGVsbGUuIERpZSBJdGFsaWVuaXNjaGUgTGlnYSB3aXJkIG5pY2h0IG51ciB1bnRlciBkZW4gU2Nobml0dCBiZXNpY2h0aWd0LCBzb25kZXJuIGRpZSBNYW5uc2NoYWZ0ZW4gdW5kIFNwaWVsZXIgc2NoaWXDn2VuIG5pY2h0IHNvIHZpZWxlLiBEaWVzZSBHcsO8bmRlIHdlaXNlbiBlaW5mYWNoIG5hY2gsIHdhcnVtIGRpZSBJdGFsaWVuaXNjaGUgTGlnYSBhbHMgKnNjaHdlcmUqIExpZ2EgZ2VrZW5uemVpY2huZXQgd2lyZC4NCg0KIyDDvGJlcnJhc2NoZW5kZSBFcmdlYm5pc3NlDQoNCmVpbiBncsO2w59lcyDDvGJlcnJhc2NoZW5kZXMgRXJnZWJuaXMgYmVzdGVodCBkYXJpbiwgZGFzcyBpbnNnZXNhbXQgNCBNZWlzdGVyc2NoYWZ0ZW4oR3Jvw59icml0YW5uaWVuLCBGcmFua3JlaWNoLCBJdGFsaWVuIHVuZCBTcGFuaWVuKSBkaWUgZ2xlaWNoZSBhdWZnZXJ1bmRldGUgTGVpc3R1bmcoamV3ZWlscyAyMSUgZGVyIHB1bmt0ZW4pIGFtIEVuZGUgZGVyIFNhaXNvbiBnZXNhbW1lbHQgaGFiZW4uIFNpZSB2ZXJmw7xnZW4gw7xiZXIgdW50ZXJzY2hpZWRsaWNoZSBUb3JkaWZmZXJueiwgRXJ3YXJ0ZXRlIFRvcmVuICwgQmVzdHNjaGllw59lciB1bmQgYmVpIG1hbmNoZW4gTWVpc3RlcnNjaGFmdGVuIGdpYnQgZXMgc29nYXIgbWVociBhbHMgNTAgJSBkZXIgTWVpc3RlcnNjaGFmdGVuLCBkaWUgd2VuaWcgVG9yZSBlcnppZWxlbi4gV2lyIGvDtm5uZW4gZGFydW50ZXIgdmVyc3RlaGVuLCBkYXNzIGRpZSBUb3JxdW90ZSBlaW5lciBNYW5uc2NoYWZ0IGtlaW5lbiBTdMOkcmtlcmVuIEVpbmZsdXNzIGF1ZiBkZW4gR2V3aW5uIG9kZXIgVmVybHVzdCBlaW5lcyBTcGllbHMgaGF0Lg0KDQpFaW5lIHdlaXRlcmUgw5xiZXJyYXNjaHVuZyBsaWVndCBkYXJhbiwgZGFzcyBkaWUgRGV1dHNjaGUgTWVpc3RlcnNjaGFmdCB3ZW5pZ2UgU3BpZWxlciBiencgU3TDvHJtZXIgaGF0LCB3ZWlsIHNpZSBudXIgMTggTWFubnNjaGFmdGVuIGhhdCwgd2VubiBkaWUgYW5kZXJlbiBMaWdhcyDDvGJlciAyMCBWZXJmw7xnZW4uIFNpZSBhYmVyIGRpZSBMaWdhIG1pdCBkZW4gYmVzdGVuIFN0w7xybWVyIGRpZSBtZWhyIGFscyBkZW4gU2Nobml0dCBzY2hpZcOfZW4uDQoNCg0KIyBLcmlzdGlzY2hlciBBdXNibGljaw0KDQpFcyBpc3QgaW1tZXIgc2Nod2VyIHNlaW5lIGVpZ2VuZSBBcmJlaXQgenUgYmV1cnRlaWxlbiwgYWJlciBudXIgZGllIGVpZ2VuZSBCZWl0ZWlsaWd0ZW4gd2lzc2VuLCB3ZWxjaGVyIEF1ZndhbmQgdW5kIHdlbGNoZSBTY2h3aWVyaWdrZWl0ZW4gc2llIGJlaSBkZXIgRXJsZWRpZ3VuZyBkZXIgQXJiZWl0IGVybGVidCBoYWJlbi4gSW4gZGllc2VyIEFyYmVpdCB3YXIgZGllIElkZWUgbWl0IGVpbmVtIEZsZXhkYXNoYm9hcmQoaW4gZGVuIGJlaWRlbiBlcnN0ZW4gdmVyc2lvbmVuKSBkaWUgRGF0ZW4genUgdmlzdWFsaXNpZXJlbiAgdW5nZWVpZ25ldC4gRGVyIEdydW5kIGRhZsO8ciBpc3QgZWluZmFjaC4gRGFtaXQga2FubiBtYW4gbmljaHQgZ2xlaWNoemVpdGlnIHZpc3VhbGlzaWVyZW4gdW5kIFRleHQgaGluenVmw7xnZW4sIGJ6dyBkZW4gQ29kZSBhbnNlaGVuLiBBYmVyIG5hY2ggendlaSBWZXJzaW9uZW4gaXN0IGVpbiAqTm90ZWJvb2sqIGbDvHIgZGllc2UgVmlzdWFsaXNpZXJ1bmcgenVtIEVpbnNhdHogZ2Vrb21tZW4gdW5kIGhhdCB1bnMgZGllIFNhY2hlbiBlcmxlaWNodGVydCB1bmQgZGllIFZpc3VhbGlzaWVydW5nZW4gaXN0IHVuc2VyZXIgTWVpbnVuZyBuYWNoIG5hY2h2b2xsemllaGJhcmVyIGdld29yZGVuLiBCZXNzZXIgaMOkdHRlbiB3aXIgZGlyZWt0IG1pdCBlaW5lbSBOb3RlYm9vayBhbmdlZmFuZ2VuIHVuZCB3aXIgd8OkcmVuIGZyw7xoIGZlcnRpZyBnZXdvcmRlbi4gQWJlciBkaWVzIGhhdCB1bnMgZXJtw7ZnbGljaHQgc293b2hsIG1pdCBGbGV4ZGFzaGJvYXJkIGFscyBhdWNoIE5vdGVib29rIHp1IGFyYmVpdGVuLiBEYXMga2FubiBmw7xyIHVucyBudXIgZWluIFZvcnRlaWwgc2Vpbi4NCg0KVmVyd2VuZGV0ZSBRdWVsbGVuDQpodHRwczovL3d3dy5kZWxmdHN0YWNrLmNvbS9kZS9ob3d0by9yL3NlcGFyYXRlLWluLXIvOiAgV3VyZGUgYmVudXR6dCwgd2VpbCB3aXIgZWluZSBTcGFsdGUgaW4gendlaSBTcGFsdGVuIGF1ZnRlaWxlbiB3b2xsdGVuLg0KDQpDaGFyYWN0ZXIgRW5jb2RpbmcgaW4gdGhlIFJTdHVkaW8gSURFIOKAkyBSU3R1ZGlvIFN1cHBvcnQ6ICBNaXQgVVRGLTggaGFiZW4gd2lyICBQcm9ibGVtZSB6dW0gRWlubGVzZW4gTWFuY2hlIENoYXJha3RlciBnZWtyaWVndCBEYWhlciBoYWJlbiB3aXIgdW5zIGRpZXNlIEVuY29kaW5nIFF1ZWxsZSBTZWl0ZSBhbmdlc2NoYXV0LCB1bSB1bnNlcmUgcGFzc2VuZGUgRW5jb2RpbmcgYXVzenV3w6RobGVuLg0KDQoJR2VsZWlzdGV0ZW4gQXJiZWl0c3plaXQNCiBadXIgRXJsZWRpZ3VuZyBkaWVzZXIgQXJiZWl0IGhhYmVuIHdpciB1bmdlZsOkaHIgNDcgU3R1bmRlbi4oaW5uZXJoYWxiIDQgV29jaGVuKSBmw7xyIGRpZSBlcnN0ZSBWZXJzaW9uIGdlYnJhdWNodC4gRsO8ciBkaWUgendlaXRlIFZlcnNpb24gMTAgU3R1bmRlbiBpbm5lcmhhbGIgZWluZXIgV29jaGUuRsO8ciBkaWUgZHJpdHRlIFZlcnNpb24gaGFiZW4gd2lyIDIzIFN0dW5kZW4gZ2VicmF1Y2h0LCB1bSBlcyAgZmVydGlnenVzdGVsbGVuLiBEYXMgZXJnaWJ0IGVpbmUgZ2VzYW10ZSBBcmJlaXRzYXVmd2FuZCB2b24gODAgU3R1bmRlbi4NCg0KDQoNCiANCg0KDQo=